<template>
  <div class="select-filter">
    <div v-for="item in data" :key="item.key" class="select-filter-item">
      <div class="select-filter-item-title">
        <span>{{ item.title }} ：</span>
      </div>
      <span v-if="!item.options.length" class="select-filter-notData">暂无数据 ~</span>
      <el-scrollbar class="scroll-box">
        <ul class="select-filter-list">
          <li
            v-for="option in item.options"
            :key="option.value"
            :class="{
              active: selected[item.key] && selected[item.key].includes(option.value)
            }"
            @click="select(item, option)"
          >
            <el-icon v-if="option.icon"><component :is="option.icon" /></el-icon>
            <span>{{ option.label }}</span>
          </li>
        </ul>
      </el-scrollbar>
    </div>
    <!-- <div class="opt-item">
      <el-button type="primary" :icon="CirclePlus">新增分组</el-button>
    </div> -->
  </div>
</template>

<script setup lang="ts" name="selectFilter">
import { ref, onBeforeMount } from "vue";
import { isType } from "@/utils";

interface optionsProps {
  value: string;
  label: string;
  icon?: string;
}

interface DataProps {
  title: string; // 列表标题
  key: string; // 当前筛选项 key 值
  multiple?: boolean; // 是否为多选
  options: optionsProps[]; // 筛选数据
}

interface FilterProps {
  data?: DataProps[]; // 选择的列表数据
  defaultValues?: any; // 默认值
}
const props = withDefaults(defineProps<FilterProps>(), {
  data: () => []
});

// 选中的值
type selectedProp = { [key: string]: string[] };
const selected = ref<selectedProp>({});

onBeforeMount(() => {
  props.data.forEach(item => {
    let transform = { ...props.defaultValues };
    // 如果默认选择的值字符串，转换为数组才好做高亮显示
    if (transform[item.key] && isType(transform[item.key]) == "string") transform[item.key] = [...props.defaultValues[item.key]];
    // 如果有默认值，就设置默认值，没有默认值就选中第一个（全部）
    selected.value[item.key] = transform[item.key] || [item.options[0]?.value];
  });
});

/**
 * @description 选择筛选项
 * @param {Object} item 选中的哪项列表
 * @param {Object} option 选中的值
 * @return void
 * */
const select = (item: DataProps, option: optionsProps) => {
  if (!item.multiple) {
    // 单选
    if (selected.value[item.key].includes(option.value)) return;
    selected.value[item.key] = [option.value];
  } else {
    // 如果选中的是第一个值，则直接设置
    if (item.options[0].value === option.value) selected.value[item.key] = [option.value];
    // 如果选择的值已经选中了，则删除选中的值
    if (selected.value[item.key].includes(option.value)) {
      // 查找当前点击元素索引
      let currentIndex = selected.value[item.key].findIndex(s => s === option.value);
      selected.value[item.key].splice(currentIndex, 1);
      // 当全部删光时，把第第一个值选中
      if (selected.value[item.key].length == 0) selected.value[item.key] = [item.options[0].value];
    } else {
      // 未选中点击值的时候，追加选中值
      selected.value[item.key].push(option.value);
      // 单选中全部并且点击到了未选中的值，把第一个值删除掉
      if (selected.value[item.key].includes(item.options[0].value)) {
        selected.value[item.key].splice(0, 1);
      }
    }
  }
  change();
};

// 触发父组件
interface FilterEmits {
  (e: "change", value: selectedProp): void;
}
const emit = defineEmits<FilterEmits>();
const change = () => {
  let params: { [key: string]: any } = { ...selected.value };
  props.data.forEach(item => !item.multiple && (params[item.key] = params[item.key].join("")));
  emit("change", params);
};
</script>

<style scoped lang="scss">
.select-filter {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  .select-filter-item {
    flex: 1;
    flex-wrap: wrap;

    display: flex;
    align-items: center;
    border-bottom: 1px dashed var(--el-border-color-light);
    &:last-child {
      border-bottom: none;
    }
    .select-filter-item-title {
      margin-top: -5px;
      span {
        font-size: 14px;
        color: var(--el-text-color-regular);
        white-space: nowrap;
      }
    }
    .select-filter-notData {
      margin: 12px 0 13px;
      font-size: 14px;
      color: var(--el-text-color-regular);
    }

    .scroll-box {
      // border: 1px solid red;
      width: calc(100vw - 370px);

      .select-filter-list {
        display: flex;
        flex: 1;
        padding: 0;
        margin: 13px 0;
        li {
          display: flex;
          align-items: center;
          padding: 5px 15px;
          margin-right: 16px;
          font-size: 13px;
          color: var(--el-color-primary);
          list-style: none;
          cursor: pointer;
          background: var(--el-color-primary-light-9);
          border: 1px solid var(--el-color-primary-light-5);
          border-radius: 32px;
          &:hover {
            color: #ffffff;
            background: var(--el-color-primary);
            border-color: var(--el-color-primary);
            transition: 0.1s;
          }
          &.active {
            font-weight: bold;
            color: #ffffff;
            background: var(--el-color-primary);
            border-color: var(--el-color-primary);
          }
          .el-icon {
            margin-right: 4px;
            font-size: 16px;
            font-weight: bold;
          }
          span {
            white-space: nowrap;
          }
        }
      }
    }
  }

  .opt-item {
    width: 100px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>
